// Author: Puyan Lotfi
// Date: Written in June 2009
// Description: Code for parsing ctags files, and maintaining editor state
//              related to ctags.

#include <QFile>
#include <QIODevice>
#include <QStringList>
#include <vector>

#include "ctagsreader.h"

#define TAB "\t"

CtagsReader::CtagsReader()
{
    // XXX
    s_ctagsCodeStart = "/^";
    s_ctagsCodeEnd = "$/;\"";
}

void CtagsReader::loadTagsFromFile(QString filename)
{
    if(!QFile::exists(filename)) return; // TODO: Throw an Exception

    QFile file(filename);
    file.open(QIODevice::ReadOnly);
    //QString tagFileText(file.readAll());

    char lineBuffer[MAX_LINE_LENGTH];

    while(-1 != file.readLine(lineBuffer, sizeof(lineBuffer)))
    {
        QString line(lineBuffer);
        QString removedCtagsStart = line.replace(s_ctagsCodeStart, TAB);
        QString removedCtagsStartAndEnd = removedCtagsStart.replace(s_ctagsCodeEnd, TAB);
        QStringList tokens = removedCtagsStartAndEnd.split(TAB, QString::SkipEmptyParts, Qt::CaseSensitive);
        QString tagname = tokens.at(0);
        QString filename = tokens.at(1);
        QString code = tokens.at(2);

        Tag tag(tagname, filename, code);
        m_tags.insert(m_tags.end(), tag);
    }
}

void CtagsReader::clearTags()
{
    m_tags.clear();
}

Tag CtagsReader::getFileAndCodeForTag(QString tagName)
{
    return getFileAndCodeForTag(tagName, false);
}

Tag CtagsReader::getFileAndCodeForTag(QString tagName, bool fromStart)
{
    Tag tag;

    return tag;
}

Tag CtagsReader::getTagByIndex(size_t i)
{
    Tag emptyTag("","","");

    if(i <= 0 || m_tags.size() <= i) return emptyTag;

    return m_tags[i];
}

std::vector<Tag> CtagsReader::getTagsByQuery(QString query)
{
    std::vector<Tag> tags;

    if(query.isEmpty() || query.isNull()) return tags;
    
    for(size_t i=0; i<size(); i++)
    {
        Tag tag = getTagByIndex(i);
        if(tag.m_tagname.contains(query, Qt::CaseInsensitive))
        {
            tags.insert(tags.end(), tag);
        }
    }
    return tags;
}

size_t CtagsReader::size()
{
    return m_tags.size();
}
